<template>
  <div class="photo-generate-container">
    <el-row :gutter="10">
      <el-col :span="24">
        <el-card class="welcome-card">
          <div class="panel-header">
            <h3>{{ title }}</h3>
            <span class="subtitle">{{ description }}</span>
            <span class="subtitle">{{ operation_steps }}</span>
          </div>
        </el-card>
      </el-col>
    </el-row>

    <el-row :gutter="10" class="mt-20">
      <!-- 左侧参数配置区域 -->
      <el-col :span="6">
        <el-card class="control-panel">
          <template #header>
            <div class="panel-header">
              <h3>参数配置</h3>
            </div>
          </template>
          
          <!-- 三段式布局: 固定头部、滚动中部、固定底部 -->
          <div class="panel-container">
            <!-- 2. 滚动内容区 - 参数表单 -->
            <div class="panel-content-scroll">
              <el-form
                ref="paramsForm"
                :model="formData"
                label-position="top"
                class="params-form"
                v-if="paramsLoaded"
              >
                <el-form-item
                  v-for="(param, key) in filteredParams"
                  :key="key"
                  :label="param.label"
                >
                  <!-- 图像上传控件 -->
                  <div v-if="param.type === 'image'" class="image-upload-block">
                    <el-upload
                      class="upload-box"
                      drag
                      :auto-upload="false"
                      :show-file-list="false"
                      :on-change="(file) => handleImageChange(file, key)"
                      :before-upload="beforeUpload"
                    >
                      <template v-if="formData[key]">
                        <div class="image-preview-container">
                          <img :src="formData[key]" class="uploaded-image-preview" />
                          <div class="image-actions">
                            <el-button 
                              type="danger" 
                              circle 
                              size="small"
                              @click.stop="removeImage(key)"
                            >
                              <el-icon><delete /></el-icon>
                            </el-button>
                          </div>
                        </div>
                      </template>
                      <div v-else class="el-upload__text">点击或拖拽上传图片</div>
                    </el-upload>
                  </div>

                  <!-- 颜色选择器 -->
                  <ColorPicker
                    v-else-if="param.type === 'colorPicker'"
                    v-model="formData[key]"
                    :show-alpha="false"
                    :preset-colors="['#ff0000', '#00ff00', '#0000ff', '#ffff00', '#00ffff', '#ff00ff']"
                    :disabled="false"
                    @change="(color) => handleColorChange(key, color)"
                  />
                  
                  <!-- 文本域 -->
                  <el-input
                    v-else-if="param.type === 'textarea'"
                    v-model="formData[key]"
                    type="textarea"
                    :rows="param.rows || 4"
                    :placeholder="param.placeholder"
                  />
                  
                  <!-- 数字输入 -->
                  <el-input-number
                    v-else-if="param.type === 'number'"
                    v-model="formData[key]"
                    :min="param.min"
                    :max="param.max"
                    :step="param.step || 1"
                    style="width: 100%"
                  />
                  
                  <!-- 选择器 -->
                  <el-select
                    v-else-if="param.type === 'select'"
                    v-model="formData[key]"
                    style="width: 100%"
                  >
                    <el-option
                      v-for="option in param.options"
                      :key="option.value"
                      :label="option.label"
                      :value="option.value"
                    />
                  </el-select>
                  
                  <!-- 文本输入 -->
                  <el-input
                    v-else
                    v-model="formData[key]"
                    :placeholder="param.placeholder"
                  />
                </el-form-item>
              </el-form>
            </div>
            
            <!-- 3. 固定底部 - 操作按钮 -->
            <div class="panel-footer-fixed">
              <el-button
                type="primary"
                @click="generateImage"
                :loading="generating"
                :disabled="!canSubmit"
              >
                <el-icon><magic-stick /></el-icon> 生成图像
              </el-button>
            </div>
          </div>
        </el-card>
      </el-col>
      
      <!-- 中间预览区域 -->
      <el-col :span="14">
        <el-card class="preview-panel">
          <template #header>
            <div class="panel-header">
              <h3>实时预览</h3>
              <div>
                <!-- 生成中显示中断按钮，生成完显示下载按钮 -->
                <template v-if="generating">
                  <el-button type="danger" @click="cancelGeneration">
                    <el-icon><close /></el-icon> 中断生成
                  </el-button>
                </template>
                <template v-else-if="generatedImage">
                  <el-button type="success" @click="downloadImage">
                    <el-icon><download /></el-icon> 下载
                  </el-button>
                </template>
              </div>
            </div>
          </template>
          
          <div class="preview-area" v-loading="generating">
            <!-- 空状态 -->
            <div v-if="!generatedImage && !generating" class="preview-placeholder">
              <div class="placeholder-content">
                <img :src="placeholderImage" alt="应用预览" class="placeholder-image" />
                <p class="placeholder-text">上传素材并配置参数后点击生成查看效果</p>
              </div>
            </div>
            
            <!-- 生成中状态 -->
            <div v-else-if="generating" class="processing-preview">
              <el-tag :type="processingStatus === 'exception' ? 'danger' : 'info'" class="status-tag">
                {{ getStatusText() }}
              </el-tag>
              <p class="processing-text">AI正在生成中...</p>
            </div>
            
            <!-- 生成结果 -->
            <div v-else class="result-preview">
              <div class="preview-image-container">
                <el-image 
                  :src="generatedImage" 
                  fit="contain"
                  class="preview-image"
                  :preview-src-list="[generatedImage]"
                  :initial-index="0"
                ></el-image>
              </div>
              <div class="image-meta">
                <p><strong>生成时间：</strong> {{ formatDate(new Date()) }}</p>
              </div>
            </div>
          </div>
        </el-card>
      </el-col>

      <!-- 右侧历史记录 -->
      <el-col :span="4">
        <el-card class="history-panel">
          <template #header>
            <div class="panel-header">
              <h3>历史记录</h3>
            </div>
          </template>
          <div class="recent-generations">
            <el-scrollbar 
              height="calc(100vh - 320px)" 
              ref="scrollbarRef"
              @scroll="handleScroll"
            >
              <el-empty 
                v-if="historyTasks.length === 0 && !loading" 
                description="暂无生成记录">
              </el-empty>
              <div v-else class="history-grid">
                <div 
                  v-for="task in historyTasks" 
                  :key="task.taskId" 
                  class="history-item"
                  @click="handleHistoryItemClick(task)"
                >
                  <div class="history-image-container">
                    <el-image 
                      v-if="task.status === 'COMPLETED' && taskImageUrls.get(task.taskId)"
                      :src="taskImageUrls.get(task.taskId)" 
                      fit="cover"
                      class="history-image"
                      :preview-src-list="[taskImageUrls.get(task.taskId)]"
                    >
                      <template #error>
                        <div class="image-error">
                          <el-icon><warning /></el-icon>
                        </div>
                      </template>
                    </el-image>
                    <div v-else class="task-status">
                      <el-tag :type="getTaskStatusType(task.status)">
                        {{ getTaskStatusText(task.status) }}
                      </el-tag>
                    </div>
                  </div>
                  <div class="history-info">
                    <span class="history-date">{{ formatDateFromString(task.createdAt) }}</span>
                    <el-tooltip 
                      v-if="task.status === 'FAILED'" 
                      :content="task.errorMsg" 
                      placement="top"
                    >
                      <el-icon class="error-icon"><warning /></el-icon>
                    </el-tooltip>
                  </div>
                </div>
              </div>
              <div v-if="loading" class="loading-more">
                <el-loading style="width: 100%;" />
                <span>加载中...</span>
              </div>
              <div v-if="noMoreData" class="no-more-data">
                没有更多记录了
              </div>
            </el-scrollbar>
          </div>
        </el-card>
      </el-col>
    </el-row>
  </div>
</template>

<script setup>
import api from '../api'
import { ref, computed, onMounted, onBeforeUnmount, watch } from 'vue'
import { useRouter } from 'vue-router'
import { ElMessage, ElLoading, ElMessageBox } from 'element-plus'
import { 
  UploadFilled, 
  Download, 
  RefreshRight, 
  Delete, 
  MagicStick,
  Close,
  Warning,
  Operation
} from '@element-plus/icons-vue'
import axios from 'axios'
import ColorPicker from './ColorPicker.vue'
import eventBus from '../utils/eventBus'

const props = defineProps({
  title: {
    type: String,
    required: true
  },
  description: {
    type: String,
    required: true
  },
  operation_steps: {
    type: String,
    required: true
  },
  workflowParams: {
    type: Object,
    required: true
  },
  workflowId: {
    type: String,
    required: true
  },
  placeholderImage: {
    type: String,
    required: true
  }
})

const router = useRouter()
const formData = ref({})
const paramsLoaded = ref(false)
const generating = ref(false)
const generatedImage = ref('')
const lastSeed = ref(null)
const generationHistory = ref([])
const paramsForm = ref(null)
const uploadedImage = ref('')
const processingProgress = ref(0)
const processingStatus = ref('')
const cancelFlag = ref(false)

// 历史任务相关状态
const historyTasks = ref([])
const currentPage = ref(0)
const pageSize = ref(10)
const loading = ref(false)
const noMoreData = ref(false)
const scrollbarRef = ref(null)
const taskImageUrls = ref(new Map())

// 根据当前路由获取对应的预览图像
const placeholderImage = computed(() => {
  const currentPath = router.currentRoute.value.path
  const imageMap = {
    '/hairrecolor': '/images/home/hairRecolor.png',
    '/facebeauty': '/images/home/faceBeauty.png',
    '/convert_to_anime': '/images/home/convertoAnime.png'
  }
  return imageMap[currentPath] || '/images/placeholder.png'
})

// 格式化日期
const formatDate = (date) => {
  return new Intl.DateTimeFormat('zh-CN', {
    year: 'numeric',
    month: '2-digit',
    day: '2-digit',
    hour: '2-digit',
    minute: '2-digit',
    second: '2-digit'
  }).format(date)
}

// 格式化字符串日期
const formatDateFromString = (dateString) => {
  if (!dateString) return ''
  const date = new Date(dateString)
  return formatDate(date)
}

// 获取状态文本
const getStatusText = () => {
  switch (processingStatus.value) {
    case 'processing':
      return '正在生成图像...'
    case 'success':
      return '生成成功'
    case 'exception':
      return '生成失败'
    default:
      return '等待中...'
  }
}

// 获取任务状态对应的类型
const getTaskStatusType = (status) => {
  switch (status) {
    case 'COMPLETED':
      return 'success'
    case 'FAILED':
      return 'danger'
    case 'PROCESSING':
      return 'warning'
    default:
      return 'info'
  }
}

// 获取任务状态对应的文本
const getTaskStatusText = (status) => {
  switch (status) {
    case 'QUEUED':
      return '等待中'
    case 'PROCESSING':
      return '生成中'
    case 'COMPLETED':
      return '已完成'
    case 'FAILED':
      return '失败'
    default:
      return status
  }
}

// 过滤掉图片类型的参数
const filteredParams = computed(() => {
  const result = {}
  Object.entries(props.workflowParams).forEach(([key, param]) => {
    result[key] = param
  })
  return result
})

// 计算是否可以提交
const canSubmit = computed(() => {
  return paramsLoaded.value
})

// 上传前钩子
const beforeUpload = (file) => {
  const isImage = file.type.startsWith('image/')
  if (!isImage) {
    ElMessage.error('只能上传图片文件!')
  }
  const isLt10M = file.size / 1024 / 1024 < 10
  if (!isLt10M) {
    ElMessage.error('文件大小不能超过 10MB!')
  }  
  return isImage
}

// 处理图片选择变化
const handleImageChange = (file, key) => {
  if (file) {
    const previewUrl = URL.createObjectURL(file.raw)
    formData.value[key] = previewUrl
    formData.value[`${key}_file`] = file.raw
  }
}

// 获取图片并转换为blob URL
const fetchAndConvertImage = async (imageUrl) => {
  try {
    const response = await api.get(imageUrl, { responseType: 'blob' })
    return URL.createObjectURL(response)
  } catch (error) {
    console.error('获取图片失败', error)
    throw error
  }
}

// 加载历史任务
const loadHistoryTasks = async (page = 0) => {
  if (loading.value || (noMoreData.value && page > 0)) return
  
  // 检查用户是否已登录
  const token = localStorage.getItem('token')
  if (!token) {
    console.error('用户未登录，无法获取历史记录')
    ElMessage.error('请先登录')
    return
  }
  
  loading.value = true
  try {
    
    const response = await api.get(`/queue/user-tasks/history/${props.workflowId}`, {
      params: {
        page: page,
        size: pageSize.value
      },
      headers: {
        'Authorization': `Bearer ${token}`
      }
    })
    
    console.log('历史记录响应:', response)
    
    const tasks = response.content || []
    
    if (page === 0) {
      historyTasks.value = tasks
    } else {
      historyTasks.value = [...historyTasks.value, ...tasks]
    }
    
    noMoreData.value = response.last || false
    currentPage.value = page
    
    await loadTaskImages(tasks)
    
  } catch (error) {
    console.error('加载历史任务失败:', error)
    console.error('错误详情:', error.response?.data)
    console.error('错误状态:', error.response?.status)
    ElMessage.error('加载历史记录失败')
  } finally {
    loading.value = false
  }
}

// 为任务加载图片
const loadTaskImages = async (tasks) => {
  for (const task of tasks) {
    if (task.status === 'COMPLETED' && task.imagePath && !taskImageUrls.value.has(task.taskId)) {
      try {
        const blobUrl = await fetchAndConvertImage(task.imagePath)
        if (blobUrl) {
          taskImageUrls.value.set(task.taskId, blobUrl)
        }
      } catch (error) {
        console.error(`加载任务 ${task.taskId} 的图片失败:`, error)
      }
    }
  }
}

// 处理滚动事件
const handleScroll = async (e) => {
  const { scrollTop, clientHeight, scrollHeight } = e.target
  if (scrollHeight - scrollTop - clientHeight < 100 && !loading.value && !noMoreData.value) {
    await loadHistoryTasks(currentPage.value + 1)
  }
}

// 处理历史记录项点击
const handleHistoryItemClick = (task) => {
  if (task.status === 'COMPLETED' && taskImageUrls.value.has(task.taskId)) {
    const blobUrl = taskImageUrls.value.get(task.taskId)
    generatedImage.value = blobUrl
  }
}

// 生成图像
const generateImage = async () => {
  if (!paramsLoaded.value) {
    ElMessage.warning('请先上传图片并等待参数加载完成')
    return
  }
  
  generating.value = true
  generatedImage.value = ''
  processingStatus.value = ''
  
  try {
    const formDataToSend = new FormData()

    Object.entries(formData.value).forEach(([key, value]) => {
      if (key.endsWith('_file')) {
        formDataToSend.append(key.replace('_file', ''), value)
      } else if (!key.endsWith('_file') && typeof value !== 'string' || !value.startsWith('blob:')) {
        formDataToSend.append(key, value)
      }
    })

    formDataToSend.append('workflowId', props.workflowId)

    const response = await api.post(
      `/queue/generate`,
      formDataToSend,
      {
        headers: {
          'Content-Type': 'multipart/form-data'
        }
      }
    )
    if (!response || typeof response !== 'object' || response.code !== 0 || !response.result || !response.result.taskId) {
      throw new Error(response?.msg || '生成任务创建失败')
    }
    const taskId = response.result.taskId
    await waitForTaskComplete(taskId)

    ElMessage.success('图像生成成功')
    
    // 通过事件总线通知其他组件刷新历史记录
    eventBus.emit('generation-success')
  } catch (error) {
    processingStatus.value = 'exception'
    console.error('生成失败', error)
    ElMessage.error('图像生成失败: ' + (error.response?.data?.error || error.message || '未知错误'))
  } finally {
    setTimeout(() => {
      generating.value = false
    }, 500)
  }
}

// 下载图像
const downloadImage = async () => {
  try {
    const response = await fetch(generatedImage.value)
    const blob = await response.blob()
    const url = window.URL.createObjectURL(blob)
    const link = document.createElement('a')
    link.href = url
    link.download = `generated-image-${formData.value.seed || 'unknown'}.png`
    document.body.appendChild(link)
    link.click()
    document.body.removeChild(link)
    window.URL.revokeObjectURL(url)
  } catch (error) {
    console.error('下载失败', error)
    ElMessage.error('图像下载失败')
  }
}

// 中断生成
const cancelGeneration = () => {
  cancelFlag.value = true
  ElMessage.warning('正在中断生成...')
}

// 等待任务完成
const waitForTaskComplete = async (taskId) => {
  processingStatus.value = 'processing'
  cancelFlag.value = false
  
  while (!cancelFlag.value) {
    try {
      const response = await api.get(`/queue/checktaskstatus?taskId=${taskId}`)
      if (!response || typeof response !== 'object' || response.code !== 0 || !response.result) {
        throw new Error(response?.msg || '任务状态获取失败')
      }
      const task = response.result
      if (task.status === 'FAILED') {
        throw new Error(task.errorMsg || '任务执行失败')
      }
      if (task.status === 'COMPLETED') {
        if (task.imagePath) {
          processingStatus.value = 'success'
          const blobUrl = await fetchAndConvertImage(task.imagePath)
          if (blobUrl) {
            generatedImage.value = blobUrl
            generationHistory.value.unshift({
              imageUrl: blobUrl,
              seed: formData.value.seed,
              params: JSON.parse(JSON.stringify(formData.value)),
              timestamp: new Date()
            })
            taskImageUrls.value.set(taskId, blobUrl)
            await loadHistoryTasks(0)
          }
          break
        } else {
          throw new Error('未找到生成的图像')
        }
      }
      await new Promise(resolve => setTimeout(resolve, 1000))
    } catch (error) {
      console.error('检查任务状态失败', error)
      processingStatus.value = 'exception'
      throw error
    }
  }
  
  if (cancelFlag.value) {
    processingStatus.value = 'exception'
    throw new Error('生成已中断')
  }
}

// 删除图片
const removeImage = (key) => {
  if (formData.value[key] && formData.value[key].startsWith('blob:')) {
    URL.revokeObjectURL(formData.value[key])
  }
  formData.value[key] = ''
  formData.value[`${key}_file`] = null
}

// 处理颜色变化
const handleColorChange = (key, color) => {
  console.log(`颜色已更改: ${key} = ${color}`)
  formData.value[key] = color
}

// 组件挂载时设置参数和历史记录
onMounted(async () => {
  // 设置默认值
  if (props.workflowParams) {
    Object.entries(props.workflowParams).forEach(([key, param]) => {
      formData.value[key] = param.default
    })
    paramsLoaded.value = true
  }
  
  await loadHistoryTasks(0)
})

// 监听 workflowParams 变化
watch(() => props.workflowParams, (newParams) => {
  if (newParams) {
    Object.entries(newParams).forEach(([key, param]) => {
      formData.value[key] = param.default
    })
    paramsLoaded.value = true
  }
}, { deep: true })

// 组件卸载前清理
onBeforeUnmount(() => {
  Object.entries(formData.value).forEach(([key, value]) => {
    if (typeof value === 'string' && value.startsWith('blob:')) {
      URL.revokeObjectURL(value)
    }
  })
  
  for (const url of taskImageUrls.value.values()) {
    URL.revokeObjectURL(url)
  }
  taskImageUrls.value.clear()
})
</script>

<style scoped>
.photo-generate-container {
  padding: 1px;
}

.mt-20 {
  margin-top:10px;
}

/* 欢迎卡片样式 */
.welcome-card {
  background-color: #fff;
}

.compact-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 0 20px;
}

.compact-header h2 {
  margin: 0;
  color: #303133;
  font-size: 20px;
}

.subtitle {
  color: #909399;
  font-size: 14px;
}

/* 面板头部样式 */
.panel-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.panel-header h3 {
  margin: 0;
  font-size: 18px;
  font-weight: bold;
}

/* 左侧控制面板样式 */
.control-panel {
  height: calc(100vh - 200px);
}

.control-panel .el-card__body {
  height: calc(100% - 60px);
  padding: 0;
  overflow: hidden;
}

/* 三段式布局容器 */
.panel-container {
  display: flex;
  flex-direction: column;
  height: calc(100vh - 280px);
}

/* 内容滚动区域 */
.panel-content-scroll {
  flex: 1;
  overflow-y: auto;
  padding: 0;
  min-height: 100px;
  width: 100%;
}

.params-form {
  padding: 0px 10px;
  width: 100%;
}

/* 确保所有表单控件都是100%宽度 */
:deep(.el-form-item) {
  width: 100%;
}

:deep(.el-input),
:deep(.el-input-number),
:deep(.el-select),
:deep(.el-textarea) {
  width: 100%;
}

/* 底部固定区域 */
.panel-footer-fixed {
  padding: 15px 20px 20px 20px;
  flex-shrink: 0;
  text-align: center;
}

.panel-footer-fixed .el-button {
  width: 80%;
  height: 45px;
  font-size: 16px;
}

/* 预览面板样式 */
.preview-panel {
  height: calc(100vh - 200px);
  display: flex;
  flex-direction: column;
  padding: 0;
}

.preview-panel .el-card__body {
  height: calc(100% - 60px);
  flex: 1;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  padding: 0;
}

.preview-area {
  flex: 1;
  height: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
  padding: 0;
}

/* 空状态样式 */
.preview-placeholder {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100%;
  padding: 0px;
  box-sizing: border-box;
}

.placeholder-content {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  height: 100%;
  width: 100%;
}

.placeholder-image {
  max-width: 100%;
  max-height: 100%;
  width: auto;
  height: 580px;
  object-fit: contain;
  border-radius: 12px;
  margin-top: 0px;
  margin-bottom: 10px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}

.placeholder-text {
  color: #606266;
  font-size: 16px;
  margin: 0;
  line-height: 1.5;
}

/* 处理中状态 */
.processing-preview {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 20px;
}

.processing-text {
  color: #606266;
  font-size: 16px;
}

/* 结果预览区域 */
.result-preview {
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  padding: 0;
}

/* 图片容器 */
.preview-image-container {
  flex: 1;
  min-height: 400px;
  position: relative;
  overflow: hidden;
  display: flex;
  justify-content: center;
  align-items: center;
}

.preview-image {
  max-width: 100%;
  max-height: 100%;
  width: auto;
  height: 600px;
  object-fit: contain;
  border-radius: 8px;
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
  padding: 0;
}

.image-meta {
  margin-top: 10px;
  text-align: left;
  background: #f8f9fa;
  border-radius: 4px;
  width: 100%;
  padding: 0;
}

.image-meta p {
  margin: 5px 0;
}

/* 历史记录面板样式 */
.history-panel {
  height: calc(100vh - 200px);
  overflow: hidden;
  display: flex;
  flex-direction: column;
}

.history-panel .el-card__body {
  flex: 1;
  overflow-y: auto;
  padding: 10px;
}

.history-grid {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 10px;
}

.history-item {
  border: 1px solid #ebeef5;
  border-radius: 4px;
  overflow: hidden;
  cursor: pointer;
  transition: all 0.3s;
}

.history-image-container {
  width: 100%;
  height: 150px;
  background-color: #f5f7fa;
  display: flex;
  justify-content: center;
  align-items: center;
  position: relative;
}

.history-image {
  width: auto;
  height: 100%;
  object-fit: cover;
}

.task-status {
  padding: 20px;
  text-align: center;
}

.history-info {
  padding: 8px;
  display: flex;
  justify-content: space-between;
  align-items: center;
  background-color: #fff;
  font-size: 12px;
  color: #909399;
}

.error-icon {
  color: #f56c6c;
}

.image-error {
  display: flex;
  flex-direction: column;
  align-items: center;
  color: #909399;
  font-size: 24px;
}

.loading-more {
  display: flex;
  justify-content: center;
  align-items: center;
  padding: 10px 0;
  color: #909399;
  font-size: 14px;
  gap: 8px;
}

.no-more-data {
  text-align: center;
  color: #909399;
  font-size: 14px;
  padding: 10px 0;
}

/* 响应式调整 */
@media (max-width: 768px) {
  .control-panel, .preview-panel, .history-panel {
    height: auto;
    margin-bottom: 20px;
  }
  
  .control-panel .el-card__body, 
  .preview-panel .el-card__body,
  .history-panel .el-card__body {
    max-height: 400px;
  }
  
  .panel-container {
    height: auto;
  }
}

/* 图像上传控件样式 */
.image-upload-block {
  margin-bottom: 16px;
  width: 100%;
}

.upload-box {
  width: 100%;
}

/* 修改 el-upload 的样式 */
:deep(.el-upload) {
  width: 100%;
}

:deep(.el-upload-dragger) {
  width: 100%;
  aspect-ratio: 3/2;
  padding: 20px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.image-preview-container {
  position: relative;
  width: 100%;
  aspect-ratio: 3/2;
  display: flex;
  justify-content: center;
  align-items: center;
}

.uploaded-image-preview {
  width: 100%;
  height: 100%;
  object-fit: contain;
  border-radius: 6px;
  background: #f5f7fa;
}

.el-upload__text {
  color: #606266;
  font-size: 14px;
  text-align: center;
  width: 100%;
}

.image-actions {
  position: absolute;
  top: 8px;
  right: 8px;
  display: flex;
  gap: 8px;
  opacity: 0;
  transition: opacity 0.3s;
}

.image-preview-container:hover .image-actions {
  opacity: 1;
}

/* 添加颜色选择器相关样式 */
:deep(.color-picker) {
  width: 100%;
  margin-bottom: 10px;
}
</style> 